package r25.engine;

import r25.character.ICharacter;
import r25.room.IRoom;

public interface IEvent {
	public enum EVENT_TYPE {
		ACTION, INFORMATION, CHECK
	}

	public enum EVENT {
		// @formatter:off
		DIE_IN_FLOODED_ROOM("Die if still in the FloodedRoom", EVENT_TYPE.CHECK, true), 
		DIE_OR_LEAVE_ROOM("Die or leave the TrappedRoom", EVENT_TYPE.CHECK, true), 
		ROOM_OUT_OF_COMPLEX("Room controlled out of the Complex", EVENT_TYPE.CHECK, true), 

		START("Start game instance", EVENT_TYPE.INFORMATION), 
		OVER("End game instance", EVENT_TYPE.INFORMATION), 
		WINNER("Game winner character", EVENT_TYPE.INFORMATION), 
		
		IS_PUSHED("Is pushed", EVENT_TYPE.INFORMATION),
		ENTER_ROOM("Room entered", EVENT_TYPE.INFORMATION),
		DEATH("Death", EVENT_TYPE.INFORMATION), 
		REVEAL_ROOM("Room revealed", EVENT_TYPE.INFORMATION), 
		PLAY_REMINDER_TOKEN("Play ReminderToken", EVENT_TYPE.INFORMATION), 
		BRING_BACK_REMINDER_TOKEN("Bring ReminderToken back", EVENT_TYPE.INFORMATION), 
		MOVED_IN_CENTRAL_ROOM("Moved in CentralRoom", EVENT_TYPE.INFORMATION), 
		ONE_ACTION_NEXT_TURN("Program only one action", EVENT_TYPE.INFORMATION),
		
		EXTRA_LOOK_ACTION("Extra Look action", EVENT_TYPE.ACTION), 
		EXTRA_CONTROL_ACTION("Extra Control action", EVENT_TYPE.ACTION),

		CHARACTER_LOOK_ACTION("Look action", EVENT_TYPE.INFORMATION),
		CHARACTER_MOVE_ACTION("Move action", EVENT_TYPE.INFORMATION),
		CHARACTER_PUSH_ACTION("Push action", EVENT_TYPE.INFORMATION),
		CHARACTER_CONTROL_ACTION("Control action", EVENT_TYPE.INFORMATION);
// @formatter:on

		private final String name;
		private final EVENT_TYPE type;
		private boolean delayedCheck;

		EVENT(String name, EVENT_TYPE type, boolean delayedCheck) {
			this.name = name;
			this.type = type;
			this.setDelayedCheck(delayedCheck);
		}

		EVENT(String name, EVENT_TYPE type) {
			this.name = name;
			this.type = type;
			this.setDelayedCheck(false);
		}

		public EVENT_TYPE getType() {
			return type;
		}

		public String getName() {
			return name;
		}

		public boolean isDelayedCheck() {
			return delayedCheck;
		}

		private void setDelayedCheck(boolean delayedCheck) {
			this.delayedCheck = delayedCheck;
		}
	}

	public abstract IRoom getRoom();

	public abstract ICharacter getCharacter();

	public abstract EVENT getType();

	public abstract GameStateTimeStamp getTimeStamp();

	public abstract void setTimeStamp(GameStateTimeStamp timeStamp);

	public abstract boolean isValid();

	public abstract void setValid(boolean valid);
}
